﻿using Sinacor.Infra.Service.Common;
using System;
using Sinacor.Infra.Service.Validation;
using Sinacor.Servico.Bovespa.Contabil;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using System.Collections.Generic; 

namespace Sinacor.Servico.Bovespa.Contabil.BusinessLogic
{
	public class DespesaNota : BaseBusinessLogic 
    {

		public DespesaNota(){}

        public void AjustarConflito(BusinessEntity.DespesaNota entity, BusinessEntity.DespesaNota conflito)
        {
            DateTime _novaData = entity.PregaoInicial.AddDays(-1);
            ResourceAccess.DespesaNota _resourceAccess = new Sinacor.Servico.Bovespa.Contabil.ResourceAccess.DespesaNota();

            conflito.PregaoFinal = _novaData;
            _resourceAccess.AlterarDespesaNota(conflito);
        }

		public void AlterarAjustarDespesaNota(BusinessEntity.DespesaNota entity)
        {
            this.ValidarDespesaNota(entity);
            
            BusinessEntity.Conflito _conflito = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Conflito();
            List<BusinessEntity.DespesaNota> _listaConflitos = new List<Sinacor.Servico.Bovespa.Contabil.BusinessEntity.DespesaNota>();

            _conflito = this.VerificarConflitoPeriodo(entity);

            if (_conflito.ExisteConflito) 
            {
                if (_conflito.PermiteAjuste)
                {
                    _listaConflitos = this.ConsultarConflitoPeriodo(entity);

                    if ((_listaConflitos != null) && (_listaConflitos.Count > 0))
                    {
                        this.AjustarConflito(entity, _listaConflitos[0]);
                    }
                    this.AlterarDespesaNota(entity); 
                }
                else
                {
                    throw new BusinessException(109244);
                }
            }
            else
            {
                this.AlterarDespesaNota(entity); 
            }
		}

		public void AlterarAjustarDespesasNota(List<BusinessEntity.DespesaNota> entityList)
        {
            foreach(BusinessEntity.DespesaNota item in entityList) 
            {
                this.AlterarAjustarDespesaNota(item);
            }
		}

		public void AlterarDespesaNota(BusinessEntity.DespesaNota entity)
        {
            this.ValidarDespesaNota(entity);
            BusinessEntity.Conflito _conflito = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Conflito(); 
            _conflito = this.VerificarConflitoPeriodo(entity);

            if (_conflito.ExisteConflito)
            {
                throw new BusinessException(109243);
            }
            else
            {
                ResourceAccess.DespesaNota _resourceAccess = new ResourceAccess.DespesaNota();
                _resourceAccess.AlterarDespesaNota(entity);             
            }
        }

		public void AlterarDespesasNota(List<BusinessEntity.DespesaNota> entityList)
        {
            foreach(BusinessEntity.DespesaNota item in entityList)
            {
                this.AlterarDespesaNota(item);
            }
		}

		private List<BusinessEntity.DespesaNota> ConsultarConflitoPeriodo(BusinessEntity.DespesaNota entity)
        {
            ResourceAccess.DespesaNota _resourceAccess = new ResourceAccess.DespesaNota();
            return _resourceAccess.ConsultarConflitoPeriodo(entity);
		}

		public List<BusinessEntity.DespesaNota> ConsultarDespesasNota(BusinessEntity.Parameter.FiltroDespesaNota parameter){
            ResourceAccess.DespesaNota _resourceAccess = new ResourceAccess.DespesaNota();
            return _resourceAccess.ConsultarDespesasNota(parameter);
		}

		public void ExcluirDespesaNota(BusinessEntity.Parameter.FiltroDespesaNotaChave parameter)
        {
            //
            Cliente.BusinessEntity.Parameter.FiltroDependenciaTipoDespesa _filtroCliente = new Sinacor.Servico.Bovespa.Cliente.BusinessEntity.Parameter.FiltroDependenciaTipoDespesa();
            Cliente.BusinessLogic.Cliente _businessLogicCliente = new Sinacor.Servico.Bovespa.Cliente.BusinessLogic.Cliente();
            Cliente.BusinessEntity.DependenciaTipoDespesa _dependencia = new Sinacor.Servico.Bovespa.Cliente.BusinessEntity.DependenciaTipoDespesa();
            BusinessEntity.DespesaNota nota = null;
            Calendario.BusinessLogic.Calendario calendario = new Sinacor.Servico.Bovespa.Calendario.BusinessLogic.Calendario();
            DateTime ultimaDataCalendario;
            //
            _filtroCliente.Codigo = parameter.Codigo;
            _dependencia = _businessLogicCliente.VerificarDependenciaTipoDespesa(_filtroCliente);
            ultimaDataCalendario = calendario.ObterUltimaDataCalendario();
            nota = this.ObterDespesaNota(parameter);

            if (_dependencia.ExisteDependencia && (nota.PregaoFinal >= ultimaDataCalendario))
            {
                throw new BusinessException(109238);   
            }
            else
            {
                ResourceAccess.DespesaNota _resourceAccess = new ResourceAccess.DespesaNota();
                _resourceAccess.ExcluirDespesaNota(parameter);
            }
		}

		public void ExcluirDespesasNota(List<BusinessEntity.Parameter.FiltroDespesaNotaChave> parameterList)
        {
            foreach (BusinessEntity.Parameter.FiltroDespesaNotaChave item in parameterList)
            {
                ExcluirDespesaNota(item);
            }
		}

		public void IncluirAjustarDespesaNota(BusinessEntity.DespesaNota entity)
        {
            this.ValidarDespesaNota(entity);

            BusinessEntity.Parameter.FiltroDespesaNotaChave _filtro = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Parameter.FiltroDespesaNotaChave();

            _filtro.Codigo = entity.Codigo;
            _filtro.PregaoInicial = entity.PregaoInicial;

            this.ValidarExistenciaDespesaNota(_filtro);

            BusinessEntity.Conflito _conflito = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Conflito();
            _conflito = this.VerificarConflitoPeriodo(entity);
            
            List<BusinessEntity.DespesaNota> _listaConflitos = new List<Sinacor.Servico.Bovespa.Contabil.BusinessEntity.DespesaNota>();

            if (_conflito.ExisteConflito)
            {
                if (_conflito.PermiteAjuste)
                {
                    _listaConflitos = this.ConsultarConflitoPeriodo(entity);

                    if ((_listaConflitos != null) && (_listaConflitos.Count > 0))
                    {
                        this.AjustarConflito(entity, _listaConflitos[0]);
                    }
                    this.IncluirDespesaNota(entity);
                }
                else
                {
                    throw new BusinessException(109237);
                }
            }
            else
            {
                this.IncluirDespesaNota(entity);            
            }
		}

		public void IncluirAjustarDespesasNota(List<BusinessEntity.DespesaNota> entityList)
        {
            foreach (BusinessEntity.DespesaNota item in entityList)
            {
                IncluirAjustarDespesaNota(item);
            }
		}

		public void IncluirDespesaNota(BusinessEntity.DespesaNota entity)
        {
            this.ValidarDespesaNota(entity);

            BusinessEntity.Parameter.FiltroDespesaNotaChave _filtroChave = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Parameter.FiltroDespesaNotaChave();            
            _filtroChave.Codigo = entity.Codigo;
            _filtroChave.PregaoInicial=entity.PregaoInicial;
            this.ValidarExistenciaDespesaNota(_filtroChave);

            BusinessEntity.Conflito _conflito = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Conflito();

            _conflito = this.VerificarConflitoPeriodo(entity);
            if (_conflito.ExisteConflito)
            {
                throw new BusinessException(109236);
            }
            else
            {
                ResourceAccess.DespesaNota _resourceAccess = new ResourceAccess.DespesaNota();
                _resourceAccess.IncluirDespesaNota(entity);
            }
		}

		public void IncluirDespesasNota(List<BusinessEntity.DespesaNota> entityList)
        {
            foreach (BusinessEntity.DespesaNota item in entityList)
            {
                this.IncluirDespesaNota(item);
            }
		}

        public BusinessEntity.DespesaNota ObterDespesaNota(BusinessEntity.Parameter.FiltroDespesaNotaChave parameter)
        {
            BusinessEntity.Parameter.FiltroDespesaNota _parameterDespesaNota = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Parameter.FiltroDespesaNota();
            _parameterDespesaNota.Codigo  = parameter.Codigo;
            _parameterDespesaNota.PregaoInicial = parameter.PregaoInicial;

            List<BusinessEntity.DespesaNota> _listaDespesas = new List<Sinacor.Servico.Bovespa.Contabil.BusinessEntity.DespesaNota>();
            _listaDespesas  = this.ConsultarDespesasNota(_parameterDespesaNota);
            if ((_listaDespesas != null) && (_listaDespesas.Count > 0))
            {
                return _listaDespesas[0];
            }
            else
            {
                return null;
            }
		}

		private void ValidarDespesaNota(BusinessEntity.DespesaNota entity)
        {
            this.ValidarDespesaNotaObrigatoriedade(entity);
            this.ValidarDespesaNotaNegocio(entity);
		}

		private void ValidarDespesaNotaNegocio(BusinessEntity.DespesaNota entity)
        {
            if (!((entity.EventoContabil.Codigo == 57) || (entity.EventoContabil.Codigo > 200)))
            { 
                throw new BusinessException(109229);
            }

            if (!(entity.ValorMinimo < Convert.ToDecimal(9999999.99)))
            {
                throw new BusinessException(109230);
            }

            if (!(entity.ValorMinimo <= entity.ValorMaximo))
            {
                throw new BusinessException(109231);
            }

            if (!(entity.ValorMaximo < Convert.ToDecimal(9999999.99)))
            {
                throw new BusinessException(109232);
            }

            if (!(entity.PregaoInicial <= entity.PregaoFinal))
            {
                throw new BusinessException(109233);
            }                
		}

		private void ValidarDespesaNotaObrigatoriedade(BusinessEntity.DespesaNota entity)
        {
            if (entity.Codigo == null)
            {
                throw new BusinessException(109223);
            }

            if (entity.PregaoInicial == null)
            {
                throw new BusinessException(109224);
            }

            if (entity.PregaoFinal == null)
            {
                throw new BusinessException(109225);
            }

            if (entity.PercentualDespesa == null)
            {
                throw new BusinessException(109226);
            }

            if (entity.ValorMinimo == null)
            {
                throw new BusinessException(109227);
            }

            if (entity.ValorMaximo == null)
            {
                throw new BusinessException(109228);
            }

            if (entity.BaseDespesa == null)
            {
                throw new BusinessException(109350);
            }

            if (entity.EventoContabil == null || entity.EventoContabil.Codigo == 0)
            {
                throw new BusinessException(109410);
            }
		}

		private void ValidarExistenciaDespesaNota(BusinessEntity.Parameter.FiltroDespesaNotaChave parameter)
        {
            ResourceAccess.DespesaNota _resourceAccess = new ResourceAccess.DespesaNota();
            if (_resourceAccess.ValidarExistenciaDespesaNota(parameter))
            {
                throw new BusinessException(109234);
            }
		}

		public BusinessEntity.Conflito VerificarConflitoPeriodo(BusinessEntity.DespesaNota entity)
        {
            List<BusinessEntity.DespesaNota> _lista = new List<Sinacor.Servico.Bovespa.Contabil.BusinessEntity.DespesaNota>();
            _lista = this.ConsultarConflitoPeriodo(entity);

            BusinessEntity.Conflito _conflito = new Sinacor.Servico.Bovespa.Contabil.BusinessEntity.Conflito();

            if (_lista.Count == 0)
            {
                _conflito.ExisteConflito = false;
            }
            else
            {
                _conflito.ExisteConflito = true;

                _conflito.PermiteAjuste = !(_lista[0].PregaoInicial > entity.PregaoInicial);
            }

            return _conflito;
		}
	}
}